'use strict';

/**
 * 角色模型
 * @param app
 */
module.exports = app => {
  const { STRING, INTEGER, BOOLEAN, DATE, TEXT, BIGINT } = app.Sequelize;

  const Role = app.model.define('sys_roles', {
    id: {
      type: BIGINT,
      primaryKey: true,
      comment: '角色ID',
    },
    name: {
      type: STRING(50),
      allowNull: false,
      unique: true,
      comment: '角色名称',
      field: 'name',
    },
    code: {
      type: STRING(50),
      allowNull: false,
      unique: true,
      comment: '角色编码',
      field: 'code',
    },
    description: {
      type: STRING(255),
      allowNull: true,
      comment: '角色描述',
      field: 'description',
    },

    status: {
      type: BOOLEAN,
      defaultValue: true,
      comment: '状态：true启用，false禁用',
      field: 'status',
    },
    createTime: {
      type: DATE,
      allowNull: false,
      comment: '创建时间',
      field: 'create_time',
      defaultValue: app.Sequelize.NOW,
    },
    updateTime: {
      type: DATE,
      allowNull: false,
      comment: '更新时间',
      field: 'update_time',
      defaultValue: app.Sequelize.NOW,
    },
  });

  // 关联关系
  Role.associate = function () {
    // 关联用户
    app.model.Role.belongsToMany(app.model.User,
      {
        through: app.model.UserRole,
        foreignKey: 'role_code',
        otherKey: 'user_id',
        targetKey: 'id', // 指定User模型的目标键为id
        as: 'users',
      });
    // 关联菜单（通过角色菜单关联表）
    app.model.Role.belongsToMany(app.model.Menu, {
      through: app.model.RoleMenu,
      foreignKey: 'roleCode', // 使用RoleMenu模型中定义的字段名
      otherKey: 'menuId',     // 使用RoleMenu模型中定义的字段名
      sourceKey: 'code',      // 指定Role模型的源键为code
      targetKey: 'id', // 指定Menu模型的目标键为id
      as: 'menus',
    });
  };

  // 在创建前生成雪花ID
  Role.beforeCreate((role) => {
    const SnowflakeUtil = require('../utils/snowflake');
    role.id = SnowflakeUtil.generateSnowflakeId();
  });

  // 自定义toJSON方法，避免字段重复
  Role.prototype.toJSON = function () {
    const values = Object.assign({}, this.get());
    // 移除重复的下划线字段
    delete values.create_time;
    delete values.update_time;
    return values;
  };

  return Role;
};

